/**
 * Simplified icon build script
 * Scans the project for used icons and extracts them from the Iconify library
 */
import fs from 'fs';
import path from 'path';
import { iconToSVG } from '@iconify/utils';

// Always include these icons even if they're not detected by scanning
const ALWAYS_INCLUDE_ICONS = [
  // Icons used in functions or conditional returns that might be hard to detect
  'lets-icons:check-fill',
  'ci:radio-unchecked',
  'ri:indeterminate-circle-line',
  'hugeicons:ai-chemistry-02',
  // Icons from baseStore.ts
  'basil:lightning-outline',
  'basil:expand-outline',
  'grommet-icons:form-view',
  'tabler:source-code',
  'hugeicons:note',
  'hugeicons:analytics-01',
  'solar:database-linear',
  'solar:box-broken',
  'hugeicons:delete-02',
  'hugeicons:plug-socket',
  'hugeicons:settings-01',
  'mingcute:hashtag-line'
];

// Recursively scan directories for files
function scanDirectory(dir, fileExtensions, result = []) {
  const files = fs.readdirSync(dir);
  
  for (const file of files) {
    const fullPath = path.join(dir, file);
    const stat = fs.statSync(fullPath);
    
    if (stat.isDirectory()) {
      // Recursively scan subdirectories
      scanDirectory(fullPath, fileExtensions, result);
    } else if (fileExtensions.includes(path.extname(file))) {
      // If file extension matches, add file to results
      result.push(fullPath);
    }
  }
  
  return result;
}

// Scan project for used icons
function scanProjectIcons() {
  try {
    console.log('Scanning project for icons...');
    
    // Scan all tsx and jsx files in the src directory
    const srcPath = path.join(__dirname, '..', '..', '..', '..');
    const files = scanDirectory(path.join(srcPath, 'src'), ['.tsx', '.jsx', '.ts']);
    
    // Extract icon names
    // 1. Match JSX attributes: icon="collection:name-with-hyphen" or icon='collection:name-with-hyphen'
    const jsxIconRegex = /icon=["']([a-zA-Z0-9_-]+:[a-zA-Z0-9_\-\.]+)["']/g;
    // 2. Match JS/TS object properties: icon: "collection:name-with-hyphen" or icon: 'collection:name-with-hyphen'
    const jsIconRegex = /icon:\s*["']([a-zA-Z0-9_-]+:[a-zA-Z0-9_\-\.]+)["']/g;
    
    const iconMatches = [];
    
    // Iterate through all files
    for (const file of files) {
      const content = fs.readFileSync(file, 'utf8');
      let match;
      
      // Scan for JSX icon attributes
      while ((match = jsxIconRegex.exec(content)) !== null) {
        iconMatches.push(match[1]);
      }
      
      // Scan for JS/TS object icon properties
      while ((match = jsIconRegex.exec(content)) !== null) {
        iconMatches.push(match[1]);
      }
    }
    
    console.log(`Found ${iconMatches.length} icon usage instances`);
    
    // Add always-include icons
    ALWAYS_INCLUDE_ICONS.forEach(iconName => {
      if (!iconMatches.includes(iconName)) {
        iconMatches.push(iconName);
      }
    });
    
    console.log(`Total icons including defaults: ${iconMatches.length}`);
    
    // Group icons by collection
    const iconsByCollection = {};
    
    iconMatches.forEach(iconName => {
      const [collection, name] = iconName.split(':');
      if (!collection || !name) return;
      
      if (!iconsByCollection[collection]) {
        iconsByCollection[collection] = new Set();
      }
      
      iconsByCollection[collection].add(name);
    });
    
    return iconsByCollection;
  } catch (error) {
    console.error('Error scanning project icons:', error);
    return {};
  }
}

// Extract icons from Iconify
async function extractIcons() {
  // Get icons used in the project
  const iconsByCollection = scanProjectIcons();
  
  let output = `// This file is auto-generated by buildIcons.js
import * as React from 'react';
import { iconToSVG } from '@iconify/utils';
// Import Iconify Icon as fallback
import { Icon as IconifyIcon } from "@iconify/react";

// Define icon collection interface
export interface IconCollection {
  prefix?: string;
  icons?: Record<string, {
    body: string;
    width?: number;
    height?: number;
    hidden?: boolean;
  }>;
  width?: number;
  height?: number;
}
`;

  // First define all icon collections
  for (const [collection, icons] of Object.entries(iconsByCollection)) {
    try {
      console.log(`Processing collection ${collection} with ${icons.size} icons...`);
      
      // Load icon data from Iconify JSON
      try {
        const fullIconsPath = require.resolve(`@iconify/json/json/${collection}.json`);
        const iconsData = JSON.parse(fs.readFileSync(fullIconsPath, 'utf8'));
        
        // Create a new icon data object
        const iconSet = {
          prefix: iconsData.prefix || collection,
          icons: {},
          width: iconsData.width || 24,
          height: iconsData.height || 24
        };
        
        // Add required icons
        for (const iconName of icons) {
          if (iconsData.icons && iconsData.icons[iconName]) {
            iconSet.icons[iconName] = iconsData.icons[iconName];
          } else {
            console.warn(`Icon "${iconName}" not found in "${collection}" collection`);
          }
        }
        
        // Export collection data
        const variableName = collection.replace(/-/g, '_');
        
        output += `
// ${collection} icon collection
export const ${variableName}: IconCollection = ${JSON.stringify(iconSet, null, 2)};
`;
      } catch (err) {
        console.error(`Could not load icon collection ${collection}:`, err.message);
      }
    } catch (error) {
      console.error(`Error processing collection ${collection}:`, error);
    }
  }
  
  // Add Icon component code
  output += `
// Icon component Props interface
interface IconProps {
  icon: string;
  width?: number | string;
  height?: number | string;
  color?: string;
  className?: string;
  style?: React.CSSProperties;
  onClick?: (e: React.MouseEvent<SVGSVGElement>) => void;
}

// Parse collection and icon name from icon name
const parseIconName = (iconName: string): { prefix: string; name: string } => {
  const parts = iconName.split(':');
  if (parts.length < 2) {
    return { prefix: '', name: iconName };
  }
  return { prefix: parts[0] || '', name: parts.slice(1).join(':') };
};

// Get icon data
const getIconData = (iconName: string) => {
  const { prefix, name } = parseIconName(iconName);
  const collectionKey = prefix.replace(/-/g, '_') as keyof typeof collections;
  
  // All icon collections
  const collections = {
${Object.keys(iconsByCollection).map(c => `    ${c.replace(/-/g, '_')},`).join('\n')}
  };
  
  const collection = collections[collectionKey];
  
  if (!collection || !collection.icons || !collection.icons[name]) {
    console.warn(\`Icon "\${name}" not found in "\${prefix}" collection\`);
    return null;
  }
  
  return {
    body: collection.icons[name].body,
    width: collection.icons[name].width || collection.width || 16,
    height: collection.icons[name].height || collection.height || 16,
  };
};

// Icon component
export const Icon = ({ 
  icon, 
  width = 24, 
  height = 24, 
  color, 
  className = '', 
  style = {},
  onClick 
}: IconProps) => {
  // Return null if icon name is empty
  if (!icon) return null;
  
  // Get icon data
  const iconData = getIconData(icon);
  
  // If local icon not found, use Iconify as fallback
  if (!iconData) {
    console.warn(\`Local icon not found: \${icon}, using Iconify fallback\`);
    return <IconifyIcon 
      icon={icon}
      width={width}
      height={height}
      color={color}
      className={className}
      style={style}
      onClick={onClick}
    />;
  }
  
  // Generate SVG from icon data
  const renderData = iconToSVG(iconData, {
    width: typeof width === 'number' ? width.toString() : width || '24',
    height: typeof height === 'number' ? height.toString() : height || '24',
  });
  
  // Build SVG attributes
  const svgAttributes = {
    width,
    height,
    viewBox: renderData.attributes.viewBox,
    className,
    style: {
      ...style,
      color: color
    },
    dangerouslySetInnerHTML: { __html: renderData.body },
    onClick,
  };
  
  // Render SVG
  return <svg {...svgAttributes} />;
};

export default Icon;
`;

  // Save file
  fs.writeFileSync(path.join(__dirname, 'icons.tsx'), output);
  console.log('Icons file generated successfully!');
}

// Execute extraction
extractIcons(); 